1. Field
One feature generally relates to inhibiting operation of malicious code in software systems, and more particularly, to methods and devices that implement execution prevention and mark memory pages as non-executable by default so as to reduce the number of instructions available to return-oriented programming exploitations in software systems.
2. Background
Computing systems executing software are under a growing array of attacks. Such attacks often insert malicious code into a computing system, and then cause the computing system to execute the malicious code. The malicious code may perform many different operations, such as, cause the computing system to run slower than normal, monitor activity on the computing system, cause the computing system to transmit or receive information that a user may not want communicated, corrupt data in persistent and non-persistent memory, and crash the computing system.
Recently, attack mechanisms sometimes called Return-Oriented Programming (ROP) exploits have been proposed. One class of ROP exploit is often referred to as a return-to-libc attack (or return-into-libc attack). A return-to-libc (or return-into-libc) attack may be identified by two attributes: (a) it uses a standard C library resident in many software systems, and (b) it jumps directly to the entry point of a libc function, not inside it. An ROP exploit is a powerful technique that allows the attacker to exploit valid code sequences in software programs without injecting any new malicious code into the processor's address space. By exploiting some bug or weakness, an attack may gain control over the next memory address from which to execute an instruction. In one example, this can happen by overwriting a return address saved on the stack. For instance, such attack may utilize buffer overflows to specify return addresses to legitimate code blocks on the stack, which have the desired effect when legitimate functions return. Other ways of attacking an instruction pointer and/or obtaining control over the next memory address are also possible. Small snippets of valid code sequences, often referred to as gadgets, may be found by the attacker, then strung together to form new malicious code sequences, thereby sidestepping defenses against code injection.
In traditional ROP exploits, the small code snippets are portions of code that end with a return or jump instruction, for example. Other instructions may also be used as gadget terminating instructions. When a function is called, an address of the instruction after the call is pushed onto a stack as an address to return to after the called function completes. Thus, the stack may include many return addresses for the processor to jump to when called functions complete. If the attack can write information to the stack, it can overwrite an intended return address with a malicious return address. This return address may correspond to one of the gadgets identified by the attack.
By manipulating multiple return addresses, the attack controlling the call stack can chain multiple gadgets together to create a malicious code sequence without ever injecting any new code into the processors address space. Through a choice of these malicious code sequences and their arrangement, the attack can induce arbitrary behavior for a malicious program composed of the string of gadgets. This type of attack is successful because in most systems code and data addresses are predictable. That is, attacks can load particular code in a first computer, view the stack of the first computer to determine how the code is being loaded, and use this information to exploit the return stack when such code is loaded in a second (target) computer. Such attack may generally rely on code being loaded the same way across different computers.
Therefore, there is a need for robust counter-measures that can inhibit return-oriented programming attacks.